﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace Utilities
{
    public class Debugger
    {

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool AllocConsole();

        [DllImport("kernel32.dll")]
        static extern IntPtr GetConsoleWindow();

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        const int SW_HIDE = 0;
        const int SW_SHOW = 5;

        public static string Source { get; set; }
        public static bool IsLogging { get; set; }
        public static bool IsWriteFile { get; set; }
        public static string LogFile { get; set; }
        public static string PathLog { get; set; }

        public static event EventHandler OnLogging;

        private static StreamWriter sw;

        public enum DebugerType
        {
            Info, Alert, Error
        }

        private static void ShowConsoleWindow()
        {
            var handle = GetConsoleWindow();

            if (handle == IntPtr.Zero)
            {
                AllocConsole();
            }
            else
            {
                ShowWindow(handle, SW_SHOW);
            }
        }

        private static void HideConsoleWindow()
        {
            var handle = GetConsoleWindow();
            ShowWindow(handle, SW_HIDE);
        }

        public static void createLog(string src)
        {
            Debugger.Source = src;
            IsLogging = true;
            IsWriteFile = false;
            showLog(true);

            Console.OutputEncoding = Encoding.UTF8;
            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.WriteLine("=============================== Debugger Program ===============================");
            Console.WriteLine("Date: "+DateTime.Now.ToLongDateString());
            Console.WriteLine("Time: " + DateTime.Now.ToShortTimeString());
            Console.WriteLine("Sourse: " + Source);
            Console.WriteLine("=============================== ---------------- ===============================");

            PathLog = Directory.GetCurrentDirectory() + "\\log\\" + DateTime.Now.ToString("dd-MM-yyyy hh-mm") + ".log";
        }
        public static void showLog(bool show)
        {
            if (show)
                ShowConsoleWindow();
            else
                HideConsoleWindow();
        }
        public static void WriteFile()
        {
            if(!Directory.Exists("log"))
                Directory.CreateDirectory(Directory.GetCurrentDirectory()+"\\log");
            log(PathLog);
            IsWriteFile = true;
        }
        public static void deleteAllLog()
        {
            string[] paths=Directory.GetFiles(Directory.GetCurrentDirectory() + "\\log");
            foreach (var p in paths)
            {
                File.Delete(p);
            }
        }
        public static void log(string info,DebugerType type){
            string loginfo="";
            if (IsLogging)
            {

                if (OnLogging != null)
                    OnLogging(null, new DebbuggerEventArgs() { Info = info });
                switch (type)
                {
                    case DebugerType.Info:
                        Console.ForegroundColor = ConsoleColor.Green;
                        loginfo = "At " + DateTime.Now.ToShortTimeString() + " # " + DateTime.Now.ToShortTimeString() + " [" + Source + "] - Info >> " + info;
                        if (IsWriteFile)
                        {
                            sw = new StreamWriter(PathLog, true);
                            sw.WriteLine(loginfo);
                            sw.Close();
                        }
                        Console.WriteLine(loginfo);
                        break;
                    case DebugerType.Alert:
                        Console.ForegroundColor = ConsoleColor.Cyan;
                        loginfo = "At " + DateTime.Now.ToShortTimeString() + " # " + DateTime.Now.ToShortTimeString() + " [" + Source + "] - Alert >> " + info;
                        if (IsWriteFile)
                        {
                            sw = new StreamWriter(PathLog, true);
                            sw.WriteLine(loginfo);
                            sw.Close();
                        }
                        Console.WriteLine(loginfo);
                        break;
                    case DebugerType.Error:
                        Console.ForegroundColor = ConsoleColor.Red;
                        loginfo = "At " + DateTime.Now.ToShortTimeString() + " # " + DateTime.Now.ToShortTimeString() + " [" + Source + "] - Error >> " + info;
                        if (IsWriteFile)
                        {
                            sw = new StreamWriter(PathLog, true);
                            sw.WriteLine(loginfo);
                            sw.Close();
                        }
                        Console.WriteLine(loginfo);
                        break;
                    default:
                        break;
                }
            }
        }
        public static void log(string info)
        {
            if (IsLogging)
            {
                if (OnLogging != null)
                    OnLogging(null, new DebbuggerEventArgs() { Info = info });
                string loginfo = "At " + DateTime.Now.ToShortTimeString() + " # " + Source + " - Info >> " + info;
                Console.ForegroundColor = ConsoleColor.Green;
                if (IsWriteFile)
                {
                    sw = new StreamWriter(PathLog, true);
                    sw.WriteLine(loginfo);
                    sw.Close();
                }
                Console.WriteLine(loginfo);
            }
        }
        public static void drawProgressBar(string info,int complete, int maxVal, int barSize, char progressCharacter)
        {
            Console.CursorVisible = false;
            int left = Console.CursorLeft;
            int top = Console.CursorTop;
            decimal perc = (decimal)complete / (decimal)maxVal;
            int chars = (int)Math.Floor(perc / ((decimal)1 / (decimal)barSize));
            string p1 = String.Empty, p2 = String.Empty;

            for (int i = 0; i < chars; i++) p1 += progressCharacter;
            for (int i = 0; i < barSize - chars; i++) p2 += progressCharacter;
            ClearCurrentConsoleLine();
            log(info);
            ClearCurrentConsoleLine();
            Console.ForegroundColor = ConsoleColor.Green;
            Console.Write(p1);
            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.Write(p2);

            Console.ResetColor();
            Console.Write(" {0}%", (perc * 100).ToString("N2"));
            Console.CursorLeft = left;
            Console.CursorTop = top;
        }
        private static void ClearCurrentConsoleLine()
        {
            int currentLineCursor = Console.CursorTop;
            Console.SetCursorPosition(0, Console.CursorTop);
            for (int i = 0; i < Console.WindowWidth; i++)
                Console.Write(" ");
            Console.SetCursorPosition(0, currentLineCursor);
        }
    }
    public class DebbuggerEventArgs : EventArgs
    {
        public string Info { get; set; }
    }

}
